/*
 * @Description: 封装axios的ajax请求，所有方法都注册了全局，调用this.$get/$post；
 * @Author: youzi
 * @Date: 2019-08-11 13:59:24
 * @LastEditors: youzi
 * @LastEditTime: 2020-09-27 08:59:05
 * @update: todo完成，已经更新为在通用方法中拦截业务码code的非200错误。符合目前的传输数据格式，并兼容旧的接口。
 */

import axios from "axios";
import { message, Modal, notification } from "ant-design-vue";
import moment from "moment";
import store from "../store";
import db from "utils/localstorage";
import router from "../router";

moment.locale("zh-cn");

let base = `${window.location.protocol}//${window.location.hostname}`;
let basePrefix = "/moral/";
// 统一配置
let ITQMS_REQUEST = axios.create({
  // baseURL: (process.env.NODE_ENV === "production" ? base : "https://mini.landlt.com") + basePrefix,
  baseURL: (process.env.NODE_ENV === "production" ? base : "http://localhost:6033") + basePrefix,
  responseType: "json",
  validateStatus(status) {
    // 200 外的状态码都认定为失败
    return status === 200;
  }
});

// 拦截请求
ITQMS_REQUEST.interceptors.request.use(
  config => {
    let expireTime = store.state.account.expireTime;
    let now = moment().format("YYYYMMDDHHmmss");
    // 让token早10秒种过期，提升“请重新登录”弹窗体验
    if (now - expireTime >= -10) {
      if (location.href.indexOf("login") < 0) {
        Modal.error({
          title: "登录已过期",
          content: "很抱歉，登录已过期，请重新登录",
          okText: "重新登录",
          mask: false,
          onOk: () => {
            return new Promise((resolve, reject) => {
              db.clear();
              // location.reload();
              router.push("/login");
              Modal.destroyAll();
              // 有 token就带上
            });
          }
        });
      }
    }
    if (store.state.account.token) {
      config.headers.Authentication = store.state.account.token;
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

/**
 * @description: 响应拦截器，封装的第一个函数的参数应该是response，写的是config不太好，后面如果要改写拦截器的话会进行改动
 * @param {response, error} 注意两个参数都应该是函数，是针对响应的处理函数
 * @return: config || error
 * @logic: 注意当code !== 200时，应该在调用函数的catch分支里写错误处理逻辑。因为直接会返回
 * @editor: youzi
 * @Date: 2019-08-14 22:39:14
 */
// 拦截响应
ITQMS_REQUEST.interceptors.response.use(
  config => {
    if (!config.data) {
      return config;
    }
    if (config.data.hasOwnProperty("code")) {
      // console.log('has code');
      if (config.data.code === 200) {
        return config;
      } else {
        if (config.data.code === 10001) {
          // 单独针对10001错误码，不提示错误，直接抛出
          return Promise.reject(config);
        }
        if (config.data.code === 401) {
          db.clear();
          // location.reload();
          router.push("/login");
          Modal.destroyAll();
          return Promise.reject(config);
        }
        let err = config.data.message
          ? config.data.message
          : "系统内部异常，请联系网站管理员";
        notification.error({
          message: "系统提示",
          description: err,
          duration: 4
        });
        return Promise.reject(config);
      }
    } else {
      // console.log('not has code');
      return config;
    }
  },
  error => {
    if (error.response) {
      let errorMessage =
        error.response.data === null
          ? "系统内部异常，请联系网站管理员"
          : error.response.data.message;
      switch (error.response.status) {
        case 404:
          notification.error({
            message: "系统提示",
            description: "很抱歉，资源未找到",
            duration: 4
          });
          break;
        case 403:
        case 401:
          notification.warn({
            message: "系统提示",
            description:
              "很抱歉，您无法访问该资源，可能是因为没有相应权限或者登录已失效",
            duration: 4
          });
          break;
        default:
          notification.error({
            message: "系统提示",
            description: errorMessage,
            duration: 4
          });
          break;
      }
    }
    return Promise.reject(error);
  }
);

const request = {
  post(url, params, contentType = 1) {
    return ITQMS_REQUEST.post(url, params, {
      transformRequest: [
        params => {
          if (contentType == 2) {
            console.log(params);
            return JSON.stringify(params);
          } else {
            let result = "";
            Object.keys(params).forEach(key => {
              if (
                !Object.is(params[key], undefined) &&
                !Object.is(params[key], null)
              ) {
                result +=
                  encodeURIComponent(key) +
                  "=" +
                  encodeURIComponent(params[key]) +
                  "&";
              }
            });
            return result;
          }
        }
      ],
      headers: {
        "Content-Type": contentType == 1 ? "application/x-www-form-urlencoded;charset=utf-8" : 'application/json;charset=utf-8'
      }
    });
  },
  put(url, params) {
    return ITQMS_REQUEST.put(url, params, {
      transformRequest: [
        params => {
          let result = "";
          Object.keys(params).forEach(key => {
            if (
              !Object.is(params[key], undefined) &&
              !Object.is(params[key], null)
            ) {
              result +=
                encodeURIComponent(key) +
                "=" +
                encodeURIComponent(params[key]) +
                "&";
            }
          });
          return result;
        }
      ],
      headers: {
        "Content-Type": "application/x-www-form-urlencoded"
      }
    });
  },
  get(url, params) {
    let _params;
    if (Object.is(params, undefined)) {
      _params = "";
    } else {
      _params = "?";
      for (let key in params) {
        if (params.hasOwnProperty(key) && params[key] !== null) {
          _params += `${key}=${params[key]}&`;
        }
      }
    }
    return ITQMS_REQUEST.get(`${url}${_params}`);
  },
  delete(url, params) {
    let _params;
    if (Object.is(params, undefined)) {
      _params = "";
    } else {
      _params = "?";
      for (let key in params) {
        if (params.hasOwnProperty(key) && params[key] !== null) {
          _params += `${key}=${params[key]}&`;
        }
      }
    }
    return ITQMS_REQUEST.delete(`${url}${_params}`);
  },
  export(url, params = {}) {
    message.loading("导出数据中");
    return ITQMS_REQUEST.post(url, params, {
      transformRequest: [
        params => {
          let result = "";
          Object.keys(params).forEach(key => {
            if (
              !Object.is(params[key], undefined) &&
              !Object.is(params[key], null)
            ) {
              result +=
                encodeURIComponent(key) +
                "=" +
                encodeURIComponent(params[key]) +
                "&";
            }
          });
          return result;
        }
      ],
      responseType: "blob"
    })
      .then(r => {
        if (r.data.size === 0) {
          throw new Error(r.data.message);
        }
        const content = r.data;
        const blob = new Blob([content]);
        const fileName = !r.headers["content-disposition"]
          ? `${new Date().getTime()}_导出结果.xlsx`
          : decodeURIComponent(
              r.headers["content-disposition"].split(";")[1].split("=")[1]
            );
        // debugger;
        if (!("msSaveBlob" in navigator)) {
          const elink = document.createElement("a");
          elink.download = fileName;
          elink.style.display = "none";
          elink.href = URL.createObjectURL(blob);
          document.body.appendChild(elink);
          elink.click();
          URL.revokeObjectURL(elink.href);
          document.body.removeChild(elink);
        } else {
          navigator.msSaveBlob(blob, fileName);
        }
      })
      .catch(r => {
        console.error(r);
        message.error("导出失败", 5);
      });
  },
  download(url, params, filename) {
    message.loading("文件传输中");
    return ITQMS_REQUEST.post(url, params, {
      transformRequest: [
        params => {
          let result = "";
          Object.keys(params).forEach(key => {
            if (
              !Object.is(params[key], undefined) &&
              !Object.is(params[key], null)
            ) {
              result +=
                encodeURIComponent(key) +
                "=" +
                encodeURIComponent(params[key]) +
                "&";
            }
          });
          return result;
        }
      ],
      responseType: "blob"
    })
      .then(r => {
        if (r.data.size === 0) {
          throw new Error(r.data.message);
        }
        const content = r.data;
        const blob = new Blob([content]);
        if (!("msSaveBlob" in navigator)) {
          const elink = document.createElement("a");
          elink.download = filename;
          elink.style.display = "none";
          elink.href = URL.createObjectURL(blob);
          document.body.appendChild(elink);
          elink.click();
          URL.revokeObjectURL(elink.href);
          document.body.removeChild(elink);
        } else {
          navigator.msSaveBlob(blob, filename);
        }
      })
      .catch(r => {
        console.error(r);
        message.error("下载失败", 5);
      });
  },
  upload(url, params) {
    return ITQMS_REQUEST.post(url, params, {
      headers: {
        "Content-Type": "multipart/form-data"
      }
    });
  }
};

export { ITQMS_REQUEST as http };
export default request;
